import java.util.ArrayList;
import java.util.ListIterator;
import java.lang.Math;

public class Stat3 {

	public ArrayList<Tuple> r;
	public int b4;
	public int b3; 
	public double n;
	public double low_a1;
	public double high_a1;
	public double low_a2;
	public double high_a2;
	public double[] widthAB; 
	public ArrayList<Range> a1;
	public ArrayList<Range> a2;
	public int[][] frequency;
	
	public Stat3(ArrayList<Tuple> r, int b3, int b4) {
		
		/*
		 * first instantiate all the stat1 and stat2 objects 
		 * then just gets the high and low of relation r for both columns and the width
		 */
		Stat1 stat1 = new Stat1(r, false);
		Stat2 stat2 = new Stat2(r, b3, b4, false);
		this.r = r;
		this.b3 = b3;
		this.b4 = b4;
		this.n  = stat1.count();
		this.low_a1 = stat1.low_a1; 
		this.high_a1= stat1.high_a1;
		this.low_a2 = stat1.low_a2;
		this.high_a2= stat1.high_a2;
		this.widthAB= stat2.getWidth(r, b3, b4);	
	}
	
	public void print(){
		for( Range r1: a1){
			for( Range r2: a2){
				int index1 = r1.returnIndex(a1, r1.getStart());
				int index2 = r2.returnIndex(a2, r2.getStart());
				System.out.println( r1.toString() +" : " + r2.toString() + " : " + frequency[index1][index2]);
			}
		}
	}
	
	public void populateHistogram(boolean verbose){
	
		this.frequency = new int[b3][b4];
		
		Range r1 = new Range();
		this.a1 = r1.returnRangeArray((int) low_a1, (int) high_a1, b3);
		this.a2 = r1.returnRangeArray((int) low_a2, (int) high_a2, b4);		
		
		//System.out.println(a1.get(0).toString());
		//System.out.println(a2.get(0).toString());

		// now the histogram has been created just need to populate the frequency list
		for (Tuple t : r) {
			// access the t.A1 and t.A2
			int index_a1;
			int index_a2;
						
			index_a1 = Range.returnIndex(this.a1 , t.A1);
			index_a2 = Range.returnIndex(this.a2 , t.A2);
			
			//System.out.println("index 1:" + index_a1);
			//System.out.println("index 2:" + index_a2);
			
			if ( index_a1 >= 0 & index_a2 >= 0) {
				frequency[index_a1][index_a2] += 1;
				//System.out.println(index_a1 +":"+ index_a2 +" : "+ frequency[index_a1][index_a2]);
			}
		}
		
		if (verbose) { this.print();}
		
	}
	
	public double returnEstimate(int r1,int s1, int r2, int s2, boolean verbose){
		double estimate= 0;
		
		//since i will get the r1 s1 r2 s2 as the input, i will get the block of the ranges matching
		ArrayList<Integer> freq_index_a1 = new ArrayList<Integer>();
		ArrayList<Integer> freq_index_a2 = new ArrayList<Integer>();
		
		// get all the Ranges that is betweek the given r1 s1 and r2 s2 and then cross multiply all of them
		// adding all the frequency counts.
		
		if (verbose) { System.out.println("now finding ranges that are subsets of the given" + "\n" +
				"R1 S1 and for the first column tuples");}
    	
		for( Range r : a1){
			if ( r.subsetRange(r1, s1) ){
				// if the range turns out to be in between the r1 and s1, add it to index
				//System.out.println("subset");
				freq_index_a1.add(r.returnIndex(a1, r.getStart()));
				if (verbose) { System.out.print(".");}
				
			}
		}
		
		if (verbose) { System.out.println("");}
		
		if (verbose) { System.out.println("now finding ranges that are subsets of the given" + "\n" +
				"R2 S2 and for the second column tuples");}

		for( Range r: a2){
			if ( r.subsetRange(r2, s2)){
				//System.out.println("subset2");
				freq_index_a2.add(r.returnIndex(a2, r.getStart()));
				if (verbose) { System.out.print(".");}
				
			}
		}
		if (verbose) { System.out.println("");}
		
		// for each index, go through the freqeuncy and add it to the estimate
    	if (verbose) { System.out.println("now going through these subsets of 2 dimentions and adding those count");}
		for( Integer i: freq_index_a1){
			for ( Integer j: freq_index_a2){
		    	if (verbose) { System.out.print(".");}
		    	// i have to add only a part of frequency as the subset of the 
		    	// given range can be a partial subset!!! 
		    	Range first = a1.get(i);
		    	Range second= a2.get(j);
		    	
		    	float percentageOfHistogram = first.getPercentage(r1, s1) * second.getPercentage(r2, s2);
				estimate += (int) Math.floor(((float) frequency[i][j] * percentageOfHistogram)) ;
			}
		}
    	if (verbose) { System.out.println("\n");}
		return estimate;
	}

}